home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Tools / MotifApp / Extras / bounce / BouncingBall.C < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-03  |  4.8 KB  |  179 lines

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //////////////////////////////////////////////////////////////////////////////
  3. //         This example code is from the book:
  4. //
  5. //           Object-Oriented Programming with C++ and OSF/Motif
  6. //         by
  7. //           Douglas Young
  8. //           Prentice Hall, 1992
  9. //           ISBN 0-13-630252-1    
  10. //
  11. //         Copyright 1991 by Prentice Hall
  12. //         All Rights Reserved
  13. //
  14. //  Permission to use, copy, modify, and distribute this software for 
  15. //  any purpose except publication and without fee is hereby granted, provided 
  16. //  that the above copyright notice appear in all copies of the software.
  17. ///////////////////////////////////////////////////////////////////////////////
  18. //////////////////////////////////////////////////////////////////////////////
  19.  
  20.  
  21. //////////////////////////////////////////////////////////
  22. // BouncingBall.C
  23. //////////////////////////////////////////////////////////
  24. #include "Application.h"
  25. #include "Stage.h"
  26. #include "BouncingBall.h"
  27. #include "ColorChooser.h"
  28. #include "InfoDialogManager.h"
  29. #include "libc.h"
  30.  
  31. #define SIZE 25
  32.  
  33. BouncingBall::BouncingBall ( Stage * stage, 
  34.                 char *colorName ) : Actor ( stage )
  35. {
  36.     // Get an initial velocity at random
  37.     
  38.     _delta.x = (int) ( SIZE * drand48() );
  39.     _delta.y = (int) ( SIZE * drand48() );
  40.     
  41.     // Initialize the current location and bounding box of the object
  42.     
  43.     _bounds.width = _bounds.height = SIZE;
  44.     _bounds.x     = _bounds.width  + 1;
  45.     _bounds.y     = _bounds.height + 1;
  46.     
  47.     _gc = NULL;
  48.     
  49.     // If a color name has been specified, try to allocate a color.
  50.     // Otherwise use the ColorChooser to let the user pick a color.
  51.     
  52.     if ( colorName )    
  53.     {
  54.     XGCValues  gcv;
  55.     Display   *dpy  = theApplication->display();
  56.     int        scr  = DefaultScreen ( dpy );
  57.     Colormap   cmap = DefaultColormap ( dpy, scr );
  58.     XColor     color, ignore;
  59.     
  60.     // If color allocation fails, use the default black pixel
  61.     
  62.     if ( XAllocNamedColor ( dpy, 
  63.                    cmap, colorName, 
  64.                    &color, &ignore ) )
  65.         gcv.foreground = color.pixel;
  66.     else
  67.         gcv.foreground = BlackPixel ( dpy, scr );
  68.     
  69.     // Create a graphics context used to draw this object
  70.     
  71.     _gc = XtGetGC ( _stage->baseWidget(), 
  72.                GCForeground, 
  73.                &gcv ); 
  74.     }
  75.     else
  76.     {
  77.     ColorChooser *colorChooser = 
  78.         new ColorChooser ( theApplication->baseWidget(),
  79.                   "colorChooser" );
  80.     
  81.     colorChooser->pickColor ( &BouncingBall::colorSelectedCallback, 
  82.                  &BouncingBall::canceledCallback, 
  83.                  (void *) this );
  84.     }
  85. }
  86.  
  87. void BouncingBall::nextFrame ( Drawable  d, 
  88.                    Dimension width, 
  89.                    Dimension height )
  90. {
  91.     if ( !_gc)   // Return if no color has been chosen yet
  92.     return;
  93.     
  94.     // Update the current position
  95.     
  96.     _bounds.x += _delta.x;
  97.     _bounds.y += _delta.y;
  98.     
  99.     // If we have hit the right wall, reposition and
  100.     // reverse the x component of the  velocity
  101.     
  102.     if ( _bounds.x + _bounds.width >= width )
  103.     {
  104.     _bounds.x = width - _bounds.width;
  105.     _delta.x  = -_delta.x;
  106.     }
  107.     else if ( _bounds.x <= 0 )  // Check for hitting the left wall
  108.     {
  109.     _bounds.x = 0;
  110.     _delta.x  = -_delta.x;
  111.     }
  112.     
  113.     // If we have hit the floor, reposition and 
  114.     // reverse the y component of the velocity
  115.     
  116.     if ( _bounds.y + _bounds.height >= height )
  117.     {
  118.     _bounds.y = height - _bounds.height;
  119.     _delta.y  = -_delta.y;
  120.     }
  121.     else if ( _bounds.y <= 0 )  // Check for bouncing off the top
  122.     {
  123.     _bounds.y = 0;
  124.     _delta.y  = -_delta.y;
  125.     }
  126.  
  127.     draw ( d );
  128. }
  129.  
  130.  
  131. void BouncingBall::draw ( Drawable  d )
  132. {   
  133.     //     Draw the object at the new location
  134.     
  135.     XFillArc ( theApplication->display(), d, _gc, 
  136.           _bounds.x,     _bounds.y, 
  137.           _bounds.width, _bounds.height, 
  138.           0, 360 * 64 );
  139. }
  140.  
  141. void BouncingBall::colorSelectedCallback ( int   red, 
  142.                        int   green, 
  143.                        int   blue, 
  144.                        void *clientData )
  145. {
  146.     BouncingBall *obj = (BouncingBall *) clientData;
  147.     
  148.     obj->colorSelected ( red, green, blue );
  149. }
  150. void BouncingBall::colorSelected ( int red, int green, int blue )
  151. {
  152.     XGCValues  gcv;
  153.     Display   *dpy  = theApplication->display();
  154.     int        scr  = DefaultScreen ( dpy );
  155.     Colormap   cmap = DefaultColormap ( dpy, scr );
  156.     XColor     color;           
  157.     
  158.     color.red   = red   * 256;
  159.     color.green = green * 256;
  160.     color.blue  = blue  * 256 ;
  161.     
  162.     if ( XAllocColor ( dpy, 
  163.               cmap, &color ) )
  164.     gcv.foreground = color.pixel;
  165.     else
  166.     gcv.foreground = BlackPixel ( dpy, scr );
  167.     
  168.     _gc = XtGetGC ( _stage->baseWidget(), 
  169.            GCForeground, 
  170.            &gcv ); 
  171. }
  172. void BouncingBall::canceledCallback ( void *clientData )
  173. {
  174.     BouncingBall *obj = (BouncingBall *) clientData;
  175.     
  176.     theInfoDialogManager->post ( "Using Black as the default color" );
  177.     obj->colorSelected ( 0, 0, 0 );
  178. }
  179.